package com.ruoyi.web.controller.project;

import java.time.LocalDate;
import java.util.Date;
import java.util.List;

import org.apache.commons.lang3.math.NumberUtils;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;

import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.page.TableDataInfo;
import com.ruoyi.common.core.text.Convert;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.exception.BusinessException;
import com.ruoyi.common.utils.AESECBPKCS5Util;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.util.ShiroUtils;
import com.ruoyi.project.domain.ProProject;
import com.ruoyi.project.domain.ProProjectContract;
import com.ruoyi.project.service.IProProjectContractService;
import com.ruoyi.project.service.IProProjectService;
import com.ruoyi.system.domain.SysDept;
import com.ruoyi.system.domain.SysUser;
import com.ruoyi.system.service.ISysDeptService;
import com.ruoyi.system.service.ISysUserService;

/**
 * 项目基本信息Controller
 * 
 * @author phil
 * @date 2020-05-28
 */
@Controller
@RequestMapping("/project/project")
public class ProProjectController extends BaseController{
	private String prefix = "project/project";

	@Autowired
	private IProProjectService proProjectService;

	@Autowired
	private ISysUserService userService;

	@Autowired
	private ISysDeptService deptService;

	@Autowired
	IProProjectContractService proProjectContractService;

	@RequiresPermissions("project:project:view")
	@GetMapping()
	public String project(){
		return prefix + "/project";
	}

	/**
	 * 查询项目基本信息列表
	 */
	@RequiresPermissions("project:project:list")
	@PostMapping("/list")
	@ResponseBody
	public TableDataInfo list(ProProject proProject){
		startPage();
		List<ProProject> list = proProjectService.selectProProjectList(proProject);
		return getDataTable(list);
	}

	/**
	 * 导出项目基本信息列表
	 */
	@RequiresPermissions("project:project:export")
	@Log(title = "项目基本信息", businessType = BusinessType.EXPORT)
	@PostMapping("/export")
	@ResponseBody
	public AjaxResult export(ProProject proProject){
		List<ProProject> list = proProjectService.selectProProjectList(proProject);
		ExcelUtil<ProProject> util = new ExcelUtil<ProProject>(ProProject.class);
		return util.exportExcel(list, "project");
	}

	/**
	 * 新增项目基本信息
	 */
	@GetMapping("/add")
	public String add(ModelMap mmap){
		LocalDate date = LocalDate.now();
		int currentYear = date.getYear();
		mmap.addAttribute("currentYear", currentYear);
		return prefix + "/add";
	}

	/**
	 * 新增保存项目基本信息
	 */
	@RequiresPermissions("project:project:add")
	@Log(title = "项目基本信息", businessType = BusinessType.INSERT)
	@PostMapping("/add")
	@ResponseBody
	public AjaxResult addSave(ProProject proProject) throws Exception{
		if(proProject != null){
			SysUser user = ShiroUtils.getSysUser();
			proProject.setCreateBy(user.getUserName());
			proProject.setCreateTime(new Date());
			// 收入预算
			String inCome = proProject.getIncome();
			// 支出预算
			String expenditure = proProject.getExpenditure();
			// 采购预算
			String procurement = proProject.getProcurement();
			if(inCome != null && !"".equals(inCome)){
				proProject.setIncome(AESECBPKCS5Util.encrypt(inCome));
			}
			if(expenditure != null && !"".equals(expenditure)){
				proProject.setExpenditure(AESECBPKCS5Util.encrypt(expenditure));
			}
			if(procurement != null && !"".equals(procurement)){
				proProject.setProcurement(AESECBPKCS5Util.encrypt(procurement));
			}
		}
		return toAjax(proProjectService.insertProProject(proProject));
	}

	/**
	 * 修改项目基本信息
	 */
	@GetMapping("/edit/{projectId}")
	public String edit(@PathVariable("projectId") Long projectId, ModelMap mmap){
		ProProject proProject = proProjectService.selectProProjectById(projectId);
		mmap.put("proProject", proProject);
		return prefix + "/edit";
	}

	/**
	 * 修改保存项目基本信息
	 */
	@RequiresPermissions("project:project:edit")
	@Log(title = "项目基本信息", businessType = BusinessType.UPDATE)
	@PostMapping("/edit")
	@ResponseBody
	public AjaxResult editSave(ProProject proProject){
		if(proProject != null){
			SysUser user = ShiroUtils.getSysUser();
			proProject.setUpdateBy(user.getUserName());
			proProject.setUpdateTime(new Date());
		}
		return toAjax(proProjectService.updateProProject(proProject));
	}

	/**
	 * 删除项目基本信息
	 */
	@RequiresPermissions("project:project:remove")
	@Log(title = "项目基本信息", businessType = BusinessType.DELETE)
	@PostMapping("/remove")
	@ResponseBody
	@Transactional
	public AjaxResult remove(String ids){
		// 校验项目是否被合同关联
		int successNum = 0;
		if(ids != null && !"".equals(ids)){
			String[] idsArray = Convert.toStrArray(ids);
			for(String proId : idsArray){
				Long projectId = NumberUtils.toLong(proId);
				ProProjectContract pc = new ProProjectContract();
				pc.setProId(projectId);
				List<ProProjectContract> proContractList = proProjectContractService.selectProProjectContractList(pc);
				if(proContractList != null && proContractList.size() > 0){
					throw new BusinessException("选中项目已关联合同，无法进行删除");
				}else{
					successNum += proProjectService.deleteProProjectById(projectId);
				}
			}
		}
		return toAjax(successNum);
	}

	/**
	 * 选择项目列表
	 *
	 * @param projectIds 部门ID
	 * @param excludeId 排除ID
	 */
	@GetMapping("/selectProjectList")
	public String selectDeptTree(Long[] projectIds, String excludeId, ModelMap mmap){
		ProProject pro = new ProProject();
		mmap.put("projectList", proProjectService.selectProProjectList(pro));
		mmap.put("excludeId", excludeId);
		return prefix + "/selectProject";
	}

	/**
	 * 下载导入模板
	 * 
	 * @return
	 */
	@RequiresPermissions("project:project:importTemplate")
	@GetMapping("/importTemplate")
	@ResponseBody
	public AjaxResult importTemplate(){
		ExcelUtil<ProProject> util = new ExcelUtil<ProProject>(ProProject.class);
		return util.importTemplateExcel("项目数据");
	}

	/**
	 * 项目导入
	 * 
	 * @param file
	 * @param updateSupport
	 * @return
	 * @throws Exception
	 */
	@RequiresPermissions("project:project:import")
	@PostMapping("/importData")
	@ResponseBody
	public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception{
		ExcelUtil<ProProject> util = new ExcelUtil<ProProject>(ProProject.class);
		List<ProProject> projectList = util.importExcel(file.getInputStream());
		// 格式校验
		String operName = ShiroUtils.getSysUser().getLoginName();
		String message = importProject(projectList, updateSupport, operName);
		return AjaxResult.success(message);
	}

	/**
	 * 导入项目
	 * 
	 * @param projectList
	 * @param isUpdateSupport
	 * @param operName
	 * @return
	 */
	public String importProject(List<ProProject> projectList, boolean isUpdateSupport, String operName) throws Exception{
		if(StringUtils.isNull(projectList) || projectList.size() == 0){
			throw new BusinessException("导入项目数据不能为空！");
		}
		// 查询系统用户
		SysUser user = new SysUser();
		user.setStatus("0");
		List<SysUser> userList = userService.selectUserList(user);

		// 查询系统单位
		SysDept dept = new SysDept();
		dept.setStatus("0");
		List<SysDept> deptList = deptService.selectDeptList(dept);

		// 查询已有项目列表
		ProProject oldProject = new ProProject();
		List<ProProject> oldProjectList = proProjectService.selectProProjectList(oldProject);

		int failureNum = 0;
		int rowNum = 1; // 起始行数
		StringBuilder successMsg = new StringBuilder();
		StringBuilder failureMsg = new StringBuilder();
		for(ProProject project : projectList){
			rowNum++;
			// WBSNO校验
			// String WBSNo = project.getWBSNo();
			// if (StringUtils.isEmpty(WBSNo))
			// {
			// failureNum++;
			// failureMsg.append("<br/>" + failureNum + "、第"+ rowNum +"行，WBSNO不允许为空");
			// }

			// 项目编号验证
			String projectNo = project.getProjectNo();
			if(StringUtils.isEmpty(projectNo)){
				failureNum++;
				failureMsg.append("<br/>" + failureNum + "、第" + rowNum + "行，项目编号不允许为空");
			}else{
				boolean hasFlag = checkHasProjectNo(projectNo, oldProjectList);
				if(hasFlag){
					failureNum++;
					failureMsg.append("<br/>" + failureNum + "、第" + rowNum + "行，项目编号在系统已存在");
				}
			}

			String projectName = project.getProjectName();
			if(StringUtils.isEmpty(projectName)){
				failureNum++;
				failureMsg.append("<br/>" + failureNum + "、第" + rowNum + "行，项目名称不允许为空");
			}

			// 项目状态
			String status = project.getStatus();
			if(StringUtils.isEmpty(status)){
				failureNum++;
				failureMsg.append("<br/>" + failureNum + "、第" + rowNum + "行，项目状态不允许为空");
			}else{
				int flag = NumberUtils.toInt(status, -1);
				if(flag == -1){
					failureNum++;
					failureMsg.append("<br/>" + failureNum + "、第" + rowNum + "行，项目状态:" + status + "在码表不存在");
				}
			}

			// 项目类型
			String projectType = project.getProTypeId();
			if(StringUtils.isEmpty(projectType)){
				failureNum++;
				failureMsg.append("<br/>" + failureNum + "、第" + rowNum + "行，项目类型不允许为空");
			}else{
				int flag = NumberUtils.toInt(projectType, -1);
				if(flag == -1){
					failureNum++;
					failureMsg.append("<br/>" + failureNum + "、第" + rowNum + "行，项目类型:" + projectType + "在码表不存在");
				}

			}

			// 项目经理手机号验证
			String pmPhone = project.getPmPhone();
			if(StringUtils.isEmpty(pmPhone)){
				failureNum++;
				failureMsg.append("<br/>" + failureNum + "、第" + rowNum + "行，手机号码不允许为空");
			}
			Long pmId = selectUserIdByPhone(pmPhone, userList);
			if(pmId == null){
				failureNum++;
				failureMsg.append("<br/>" + failureNum + "、第" + rowNum + "行，手机号码" + pmPhone + "在系统不存在");
			}else{
				project.setPmId(pmId);
			}

			// 部门转换
			String deptName = project.getDeptName();
			if(StringUtils.isEmpty(deptName)){
				failureNum++;
				failureMsg.append("<br/>" + failureNum + "、第" + rowNum + "行，所属部门不允许为空");
			}
			Long deptId = selectDeptIdByName(deptName, deptList);
			if(deptId == null){
				failureNum++;
				failureMsg.append("<br/>" + failureNum + "、第" + rowNum + "行，部门名称：" + deptName + "在系统不存在");
			}else{
				project.setDeptId(deptId);
			}

			// 收入预算、加密处理
			String income = project.getIncome();
			if(StringUtils.isNotEmpty(income)){
				project.setIncome(AESECBPKCS5Util.encrypt(income));
			}
			// 支出预算
			String expenditure = project.getExpenditure();
			if(StringUtils.isNotEmpty(expenditure)){
				project.setExpenditure(AESECBPKCS5Util.encrypt(expenditure));
			}
			// 采购预算
			String procurement = project.getProcurement();
			if(StringUtils.isNotEmpty(procurement)){
				project.setProcurement(AESECBPKCS5Util.encrypt(procurement));
			}

			project.setCreateTime(new Date());
			project.setCreateBy(operName);
		}

		if(failureNum > 0){
			failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 处数据格式不正确，错误如下：");
			throw new BusinessException(failureMsg.toString());
		}else{
			// 插入项目数据
			int successNum = proProjectService.insertProProjects(projectList);
			successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + successNum + " 条，数据如下：");
		}
		return successMsg.toString();
	}

	/**
	 * 检查项目编号是否存在
	 * 
	 * @param projectNo
	 * @param oldProjectList
	 * @return
	 */
	private boolean checkHasProjectNo(String projectNo, List<ProProject> oldProjectList){
		boolean hasFlag = false;
		if(oldProjectList != null && oldProjectList.size() > 0 && projectNo != null && !"".equals(projectNo)){
			for(ProProject project : oldProjectList){
				if(projectNo.trim().equals(project.getProjectNo())){
					hasFlag = true;
					break;
				}
			}
		}
		return hasFlag;
	}

	/**
	 * 通过手机号核对pmId
	 * 
	 * @return
	 */
	public Long selectUserIdByPhone(String phoneNumber, List<SysUser> userList){
		Long userId = null;
		if(userList != null && userList.size() > 0){
			for(SysUser user : userList){
				if(phoneNumber.trim().equals(user.getPhonenumber())){
					userId = user.getUserId();
					break;
				}
			}
		}
		return userId;
	}

	/**
	 * 通过手机号核对pmId
	 * 
	 * @return
	 */
	public Long selectDeptIdByName(String deptName, List<SysDept> deptList){
		Long deptId = null;
		if(deptList != null && deptList.size() > 0){
			for(SysDept dept : deptList){
				if(deptName.trim().equals(dept.getDeptName())){
					deptId = dept.getDeptId();
					break;
				}
			}
		}
		return deptId;
	}

}
